package com.browsesoft.synchronserver;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.Remote;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.browsesoft.PropertiesService;

/**
 * 同步服务收集器 根据属性文件中配置的SynchronIps 收集其他运行的服务的rmi同步服务
 * 
 */
public class SynchronServerGather {

	private static SynchronServerGather self = new SynchronServerGather();

	/**
	 * 存放同步服务的集合
	 */
	private Map servers = new HashMap();

	/**
	 * 同步服务地址
	 */
	private static List ips = new LinkedList();

	/**
	 * 收集同步服务地址
	 */
	static {
		try {
			// 得到远程同步服务器地址
			Element elem = (Element) PropertiesService.getDocument()
					.getElementsByTagName("SynchronIps").item(0);
			NodeList list = elem.getElementsByTagName("ip");
			for (int i = 0; i < list.getLength(); i++) {
				Element ip = (Element) list.item(i);
				ips.add(ip.getAttribute("address"));
			}
		} catch (RuntimeException e) {
			System.out.println("未找到同步服务器配置");
		}
	}

	private SynchronServerGather() {
		self = this;
	}

	public static SynchronServerGather getInstance() {
		return self;
	}

	/**
	 * 得到其他rmi服务
	 */
	public Map getSynchronServers() {
		// 得到自己的ip地址
		String localIp = this.getLocalHotIP();
		// rmi端口号
		String port = this.getRMIPort();
		// 得到远程同步服务
		Iterator iter = ips.iterator();
		while (iter.hasNext()) {
			String ip = (String) iter.next();
			// 如果是本机，不处理
			if (localIp.equals(ip)) {
				continue;
			}
			// 如果已存在该服务，不处理
			if (this.servers.get(ip) != null) {
				continue;
			}
			// 如果没有该远程服务,查找远程同步服务
			Remote remote = searchSynchronServer(ip, port);
			if (remote != null) {
				this.servers.put(ip, remote);
			}
		}
		return this.servers;
	}

	private String getLocalHotIP() {
		try {
			InetAddress local = InetAddress.getLocalHost();
			return local.getHostAddress();
		} catch (UnknownHostException e) {
			throw new RuntimeException("获取本机ip发生异常", e);
		}
	}

	/**
	 * 清除无效的同步服务
	 */
	public void removeSynchronServer(String ip) {
		this.servers.remove(ip);
	}

	/**
	 * 查找远程同步服务
	 */
	private Remote searchSynchronServer(String ip, String port) {
		// 根据ip查找远程同步服务
		Remote result = null;
		try {
			result = Naming.lookup("rmi://" + ip + ":" + port
					+ "/SynchronServer");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return result;
	}

	private String getRMIPort() {
		try {
			String result = PropertiesService.getProperty("rmi", "port");
			return result;
		} catch (Exception e) {
			throw new RuntimeException("获取rmi端口号错误", e);
		}

	}

}
